#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import logging
import os
import sys
import shutil
import hashlib

execfile(os.path.join(sys.path[0], "framework.py"))

from unittest import TestCase, TestLoader, TextTestRunner
from oriolus.trotter.core import FetchError
from oriolus.trotter.fetchers.persistentfetcher import PersistentFetcher
from mockhttpserver import Runner

log_name = "trotter.log.txt"
log_path = os.path.join(os.getcwd(), log_name)
logging.basicConfig(level = logging.ERROR, format = "[%(levelname)s] %(message)s", )
#logging.basicConfig(level = logging.DEBUG, filename = log_name, format = "%(asctime)-15s [%(thread)d] %(levelname)-5s %(name)s - %(message)s", )

class TestPersistentFetcher(TestCase):
    cache = os.path.abspath("./testdata/cache")
    runner = Runner()
    
    def get_md5(self, filename):
        """Calcutes md5 hash of file"""
        md5 = hashlib.md5()
        size = os.path.getsize(filename)
        file = open(filename, "r")
        md5.update(file.read(size))
        file.close()
        
        return md5.digest()

    def setUp(self):
        self.runner.start()
        if not os.path.exists(self.cache):
            os.makedirs(self.cache)
            
        self.ftp_url = "ftp://apache.rinet.ru/pub/mirror/apache.org/dist/httpd/KEYS"
        self.ftp_name = "KEYS"
#        self.ftp_url = "ftp://ftp.ncbi.nlm.nih.gov/blast/documents/seedtop.html"
#        self.ftp_name = "seedtop.html"
        
    def tearDown(self):
        if os.path.exists(self.cache):
            shutil.rmtree(self.cache)
        if os.path.exists(self.cache): 
            for root, dirs, files in os.walk(self.cache, topdown=False):
                for name in files:
                    os.remove(os.path.join(root, name))
        self.runner.stop()        

    def test_local_1(self):
        fetcher = PersistentFetcher(self.cache)
        fetcher.get("http://localhost:8888/testdata/file01.txt")
        
        self.assertEqual(True, os.path.exists(os.path.join(self.cache, "file01.txt")))
        self.assertEqual(os.path.getsize("testdata/file01.txt"), os.path.getsize(os.path.join(self.cache, "file01.txt")))

    def test_local_2(self):
        fetcher = PersistentFetcher(self.cache)
        file1 = fetcher.get("http://localhost:8888/testdata/file01.zip")
        shutil.move(file1, os.path.join(self.cache, "file01.zip.tmp"))
        file2 = fetcher.get("http://localhost:8888/testdata/file01.zip")
        
        self.assertEqual(True, os.path.exists(os.path.join(self.cache, "file01.zip")))
        self.assertEqual(os.path.getsize("testdata/file01.zip"), os.path.getsize(os.path.join(self.cache, "file01.zip")))
        
    def test_remote_1(self):
        fetcher = PersistentFetcher(self.cache)
        filename1 = fetcher.get("http://www.python.org/~anthony/anthonypub.asc")
        file1_size = os.path.getsize(filename1)
        file1_md5 = self.get_md5(filename1)
        
        file1 = open(filename1, "rb")
        filename2 = os.path.join(self.cache, "anthonypub.asc.tmp")
        file2 = open(filename2, "wb")
        
        file2.write(file1.read(60))
        
        file1.close()
        file2.close()
        
        filename2 = fetcher.get("http://www.python.org/~anthony/anthonypub.asc")
        
        self.assertEqual(True, os.path.exists(os.path.join(self.cache, "anthonypub.asc")))
        self.assertEqual(file1_size, os.path.getsize(filename2))
        self.assertEqual(file1_md5, self.get_md5(filename2))
        
    def test_remote_2(self):
        fetcher = PersistentFetcher(self.cache)
        filename1 = fetcher.get(self.ftp_url)
        file1_size = os.path.getsize(filename1)
        file1_md5 = self.get_md5(filename1)
        
        file1 = open(filename1, "rb")
        filename2 = os.path.join(self.cache, self.ftp_name + ".tmp")
        file2 = open(filename2, "wb")
        
        file2.write(file1.read(60))
        
        file1.close()
        file2.close()
        
        filename2 = fetcher.get(self.ftp_url)
        
        self.assertEqual(True, os.path.exists(os.path.join(self.cache, self.ftp_name)))
        self.assertEqual(file1_size, os.path.getsize(filename2))
        self.assertEqual(file1_md5, self.get_md5(filename2))

    def test_incorrect_url_1(self):
        fetcher = PersistentFetcher(self.cache)
        self.assertRaises(FetchError, fetcher.get, "http://www.incorrecturl.ru/index.html")
        
    def test_incorrect_url_2(self):
        fetcher = PersistentFetcher(self.cache)
        self.assertRaises(FetchError, fetcher.get, "http://www.yandex.ru/shmyndex.html")
        
    def test_incorrect_url_3(self):
        fetcher = PersistentFetcher(self.cache)
        self.assertRaises(FetchError, fetcher.get, "C:\\WINDOWS\\system32\\notepad.exe")
    
    def test_abort_1(self):
        fetcher = PersistentFetcher(self.cache, timeout = 5)
        self.assertRaises(FetchError, fetcher.get, "http://localhost:8888/testdata/error.txt")
        
    def test_local_3(self):
        fetcher = PersistentFetcher(self.cache, timeout = 30)
        fetcher.get("http://localhost:8888/testdata/error.txt")
        
        self.assertEqual(True, os.path.exists(os.path.join(self.cache, "error.txt")))
        self.assertEqual(os.path.getsize("testdata/error.txt"), os.path.getsize(os.path.join(self.cache, "error.txt")))
        
if __name__ == "__main__":
    suite = TestLoader().loadTestsFromTestCase(TestPersistentFetcher)
    TextTestRunner(verbosity=2).run(suite)
    